package top.cluski.feieprint.web;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.mybatisflex.core.query.QueryWrapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import top.cluski.feieprint.domain.RespVO;
import top.cluski.feieprint.domain.dto.FeiEPrintErrorContext;
import top.cluski.feieprint.domain.dto.PrintSettingDTO;
import top.cluski.feieprint.domain.dto.QueryPrinterDTO;
import top.cluski.feieprint.entity.PrinterEntity;
import top.cluski.feieprint.exception.FeiEPrintException;
import top.cluski.feieprint.service.EMailService;
import top.cluski.feieprint.service.FeiEPrintService;

import java.util.HashMap;
import java.util.List;

@RestController
@RequestMapping("/feie-print")
@Slf4j
public class FeiEPrintController {

    @Resource
    FeiEPrintService feiEPrintService;
    @Resource
    EMailService eMailService;

    @PostMapping(value = "/print")
    public ResponseEntity<String> print(@RequestBody String body) {
        try {
            JSONObject jsonObject = JSON.parseObject(body);
            // feiEPrintDTO.validate();
            feiEPrintService.print(jsonObject);

            HashMap<String, String> resp = new HashMap<>();
            resp.put("status", "ok");
            return new ResponseEntity<>(JSONObject.toJSONString(resp), HttpStatus.OK);
        } catch (Exception e) {
            return printErrorProcess(e);
        }
    }

    @PostMapping(value = "/printById")
    public ResponseEntity<String> printById(@RequestBody String body) {
        try {
            JSONObject jsonObject = JSON.parseObject(body);
            // feiEPrintDTO.validate();
            feiEPrintService.printById(jsonObject);

            HashMap<String, String> resp = new HashMap<>();
            resp.put("status", "ok");
            return new ResponseEntity<>(JSONObject.toJSONString(resp), HttpStatus.OK);
        } catch (Exception e) {
            return printErrorProcess(e);

        }
    }

    @PostMapping("/test-print/{printerId}")
    public RespVO<Void> testPrint(@PathVariable Integer printerId) {
        feiEPrintService.testPrint(printerId);
        return RespVO.success();
    }

    @PostMapping("/copyPrinter/{printerId}")
    public RespVO<Void> copyPrinter(@PathVariable Integer printerId) {
        feiEPrintService.copyPrinter(printerId);
        return RespVO.success();
    }

    @PostMapping("/printer")
    public RespVO<Void> addPrinter(@RequestBody PrinterEntity printerEntity) {
        feiEPrintService.getMapper().insertSelective(printerEntity);
        return RespVO.success();
    }

    @PutMapping("/printer")
    public RespVO<Void> editPrinter(@RequestBody PrinterEntity printerEntity) {
        feiEPrintService.getMapper().update(printerEntity);
        return RespVO.success();
    }

    @DeleteMapping("/printer/{id}")
    public RespVO<Void> deletePrinter(@PathVariable Integer id) {
        feiEPrintService.getMapper().deleteById(id);
        return RespVO.success();
    }

    @PostMapping("/printers")
    public RespVO<List<PrinterEntity>> getPrinters(@RequestBody QueryPrinterDTO queryPrinterDTO) {
        return RespVO.success(feiEPrintService
                .list(new QueryWrapper().like(PrinterEntity::getName, queryPrinterDTO.getPrinterName())));
    }

    @PostMapping("/label-size/{id}/{width}/{height}")
    public RespVO<Void> saveLabelSize(@PathVariable Integer id, @PathVariable Integer width,
                                      @PathVariable Integer height) {
        feiEPrintService.saveLabelSize(id, width, height);
        return RespVO.success();
    }

    @PostMapping("/print-setting")
    public RespVO<Void> savePrintSetting(@RequestBody PrintSettingDTO printSettingDTO) {
        feiEPrintService.savePrintSetting(printSettingDTO);
        return RespVO.success();
    }

    private ResponseEntity<String> printErrorProcess(Exception e) {
        log.error("打印失败", e);
        if (e instanceof FeiEPrintException feiEPrintException) {
            eMailService.sendFeiePrinterError(feiEPrintException.getErrorContext());
            return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);
        } else {
            eMailService.sendFeiePrinterError(new FeiEPrintErrorContext(FeiEPrintErrorContext.MainError.PRINT_ERROR,
                    FeiEPrintErrorContext.SubError.UNKNOWN_ERROR, ""));
            return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
}
